package ecc;

import java.awt.Color;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Random;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * JFrameECCLite.java
 *
 * Created on Jan 3, 2011, 4:00:40 PM
 */
/**
 *
 * @author mjunior
 */
public class JFrameECCLiteDSA extends javax.swing.JFrame {

	private SecureRandom rand;
	private BigInteger privateKey;
	private EPoint publicKey;
	private ECurve curve;
	private int numBits;

	/** Creates new form JFrameECCLite */
	public JFrameECCLiteDSA() {
		initComponents();

		//Centralizes the JFrame
		setLocationRelativeTo(null);

		byte[] randSeed = new byte[20];
		(new Random()).nextBytes(randSeed);
		/*
		for (int i = 0; i < randSeed.length; i++) {
		randSeed[i] = (byte)i;
		}
		//*/
		this.rand = new SecureRandom(randSeed);
	}

	private boolean genKeyPair(int bits) {
		System.out.print("Generating key pair for " + bits + "-bit ...");

		this.numBits = bits;
		this.curve = ECurve.getStandardCurve(this.numBits); // load curve equation for E

		Object[] pair = ESigns.makeKeyPair(curve, rand);
		if (pair == null) {
			this.jLabelError.setText("unable to make key pair!");
			return false;
		}

		this.privateKey = (BigInteger) pair[0];
		this.publicKey = (EPoint) pair[1];

		return true;
	}

	private byte[] sign(String message) throws NoSuchAlgorithmException {
		System.out.println("Testing " + this.numBits + "-bit ECDSA signing");

		ESigns sv = new ESigns();
		byte[] msg = message.getBytes();
		byte[] r, sig = null;

	
		long elapsed = -System.currentTimeMillis();
		int tests = 10;
		for (int i = 0; i < tests; i++) {
			r = sv.init(ESigns.ECDSA, this.curve, MessageDigest.getInstance("SHA"), rand);
			//System.out.print("i");
			//sv.update(msg, 0, i); // sign the first i characters of msg
			sv.update(msg, 0, msg.length); // signs the whole msg
			//System.out.print("u");
			sig = sv.sign(privateKey);
			//System.out.print("s");

		}
		elapsed += System.currentTimeMillis();
		this.jLabelTimeSign.setText(elapsed + " ms");

		System.out.println(" done in " + 1.0 * elapsed / tests + " ms/sig.");

		return sig;
	}

	private boolean verify(String message, byte[] sig) throws NoSuchAlgorithmException {

		ESigns sv = new ESigns();
		byte[] msg = message.getBytes();

		System.out.println("Testing " + this.numBits + "-bit ECDSA verification");

		boolean ok = false;

		int tests = 10;
		long elapsed = -System.currentTimeMillis();
		for (int i = 0; i < tests; i++) {
			byte[] r = sv.init(ESigns.ECDSA, this.curve, MessageDigest.getInstance("SHA"), publicKey, sig, 0);
			//System.out.print("i");
			//sv.update(msg, 0, i); // verify the first i characters of msg
			sv.update(msg, 0, msg.length); // verify the whole msg
			//System.out.print("u");

			ok = sv.verify();
		}
		elapsed += System.currentTimeMillis();
		this.jLabelTimeVerif.setText(elapsed + " ms");
		System.out.println(" done in " + 1.0 * elapsed / tests + " ms/sig.");

		return ok;
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        jPanelContainer = new javax.swing.JPanel();
        jTextFieldMsg = new javax.swing.JTextField();
        jComboBoxCurveSize = new javax.swing.JComboBox();
        jTextFieldSignature = new javax.swing.JTextField();
        jButtonSign = new javax.swing.JButton();
        jButtonVerify = new javax.swing.JButton();
        jLabelTimeSign = new javax.swing.JLabel();
        jLabelTimeVerif = new javax.swing.JLabel();
        jLabelResult = new javax.swing.JLabel();
        jLabelMsg = new javax.swing.JLabel();
        jLabelSignature = new javax.swing.JLabel();
        jLabelCurve = new javax.swing.JLabel();
        jLabelPublic = new javax.swing.JLabel();
        jLabelPrivate = new javax.swing.JLabel();
        jLabelPubValue = new javax.swing.JLabel();
        jLabelPrivValue = new javax.swing.JLabel();
        jButton1 = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JSeparator();
        jLabelError = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("ECCLite: EC-DSA");
        setMinimumSize(new java.awt.Dimension(800, 300));
        getContentPane().setLayout(new java.awt.GridBagLayout());

        jPanelContainer.setLayout(new java.awt.GridBagLayout());

        jTextFieldMsg.setText("Mensagem");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 6;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 4, 0);
        jPanelContainer.add(jTextFieldMsg, gridBagConstraints);

        jComboBoxCurveSize.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "160", "192", "224", "256", "384", "521" }));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(5, 0, 4, 0);
        jPanelContainer.add(jComboBoxCurveSize, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 9;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(1, 0, 4, 0);
        jPanelContainer.add(jTextFieldSignature, gridBagConstraints);

        jButtonSign.setText("Assinar");
        jButtonSign.setEnabled(false);
        jButtonSign.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonSignActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jButtonSign, gridBagConstraints);

        jButtonVerify.setText("Verificar");
        jButtonVerify.setEnabled(false);
        jButtonVerify.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButtonVerifyActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 11;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jButtonVerify, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 7;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 0);
        jPanelContainer.add(jLabelTimeSign, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 2;
        gridBagConstraints.gridy = 11;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 0);
        jPanelContainer.add(jLabelTimeVerif, gridBagConstraints);

        jLabelResult.setText(" ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 12;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
        jPanelContainer.add(jLabelResult, gridBagConstraints);

        jLabelMsg.setLabelFor(jTextFieldMsg);
        jLabelMsg.setText("Mensagem:");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 5;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 2, 0);
        jPanelContainer.add(jLabelMsg, gridBagConstraints);

        jLabelSignature.setLabelFor(jLabelSignature);
        jLabelSignature.setText("Assinatura (r,s):");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 8;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(20, 0, 2, 0);
        jPanelContainer.add(jLabelSignature, gridBagConstraints);

        jLabelCurve.setText("Curva: ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelCurve, gridBagConstraints);

        jLabelPublic.setText("Pública: ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelPublic, gridBagConstraints);

        jLabelPrivate.setText("Privada: ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelPrivate, gridBagConstraints);

        jLabelPubValue.setText("-");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelPubValue, gridBagConstraints);

        jLabelPrivValue.setText("-");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        jPanelContainer.add(jLabelPrivValue, gridBagConstraints);

        jButton1.setText("Gerar Chaves");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.gridwidth = 2;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(11, 0, 5, 0);
        jPanelContainer.add(jButton1, gridBagConstraints);
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(9, 0, 9, 0);
        jPanelContainer.add(jSeparator1, gridBagConstraints);

        jLabelError.setText(" ");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 13;
        gridBagConstraints.gridwidth = 3;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(9, 0, 0, 0);
        jPanelContainer.add(jLabelError, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(6, 6, 6, 6);
        getContentPane().add(jPanelContainer, gridBagConstraints);

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void jButtonSignActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonSignActionPerformed
		try {
			byte[] signature = this.sign(this.jTextFieldMsg.getText());
			this.jTextFieldSignature.setText(Util.getHexString(signature));

			this.jButtonVerify.setEnabled(true);
			this.jLabelError.setText(" ");
		} catch (Exception ex) {
			ex.printStackTrace();
			this.jLabelError.setText(ex.toString());
			this.jButtonVerify.setEnabled(false);
		}


    }//GEN-LAST:event_jButtonSignActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed

		boolean success = false;
		try {
			success = this.genKeyPair(Integer.parseInt(this.jComboBoxCurveSize.getSelectedItem().toString()));
			this.jLabelError.setText(" ");
		} catch (Exception ex) {
			this.jLabelError.setText(ex.toString());
		}

		if (success) {
			this.jLabelPrivValue.setText(this.privateKey.toString());
			this.jLabelPubValue.setText(this.publicKey.toString());
		} else {
			this.jLabelPrivValue.setText("-");
			this.jLabelPubValue.setText("-");
		}
		this.jButtonSign.setEnabled(success);
		//this.jButtonVerify.setEnabled(false);


    }//GEN-LAST:event_jButton1ActionPerformed

	private void showResult(boolean ok) {
		if (ok) {
			this.jLabelResult.setText("OK");
			this.jLabelResult.setForeground(Color.blue);
		} else {
			this.jLabelResult.setText("INVALIDA");
			this.jLabelResult.setForeground(Color.red);
		}
	}

    private void jButtonVerifyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButtonVerifyActionPerformed

		boolean result = false;
		try {
			result = this.verify(this.jTextFieldMsg.getText(), Util.hexStringToByteArray(this.jTextFieldSignature.getText()));
			this.jLabelError.setText(" ");
		} catch (Exception ex) {
			ex.printStackTrace();
			this.jLabelError.setText(ex.toString());
		}

		this.showResult(result);
    }//GEN-LAST:event_jButtonVerifyActionPerformed

	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {

			public void run() {
				new JFrameECCLiteDSA().setVisible(true);
			}
		});
	}
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButtonSign;
    private javax.swing.JButton jButtonVerify;
    private javax.swing.JComboBox jComboBoxCurveSize;
    private javax.swing.JLabel jLabelCurve;
    private javax.swing.JLabel jLabelError;
    private javax.swing.JLabel jLabelMsg;
    private javax.swing.JLabel jLabelPrivValue;
    private javax.swing.JLabel jLabelPrivate;
    private javax.swing.JLabel jLabelPubValue;
    private javax.swing.JLabel jLabelPublic;
    private javax.swing.JLabel jLabelResult;
    private javax.swing.JLabel jLabelSignature;
    private javax.swing.JLabel jLabelTimeSign;
    private javax.swing.JLabel jLabelTimeVerif;
    private javax.swing.JPanel jPanelContainer;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JTextField jTextFieldMsg;
    private javax.swing.JTextField jTextFieldSignature;
    // End of variables declaration//GEN-END:variables
}
